package com.tc.zigbee.zcl;

import java.util.LinkedList;
import java.util.List;

import com.tc.util.DataUtil;
import com.tc.zigbee.entity.Endpoint;
import com.tc.zigbee.entity.ZigbeeScene;
import com.tc.zigbee.ha.HAConstants;

public class ZclCommandCreator {
	static byte[] onoff(byte tsec, byte ci){
		ZclRawCommand c = new ZclRawCommand();
		c.frameControl = 0x01;
		c.manufactureCode = null;
		c.transactionSnum = tsec;
		c.commandIdentifier = ci;
		return c.frame();
	}
	
	static public byte[] on(byte tsec){

		return onoff(tsec, (byte)0x01);
	}
	static public byte[] off(byte tsec){

		return onoff(tsec, (byte)0x00);
	}
	static public byte[] toggle(byte tsec){

		return onoff(tsec, (byte)0x02);
	}
	
	static public byte[] read(byte tsec, List<Short> attribs){
		ZclRawCommand c = new ZclRawCommand();
		c.frameControl = 0x00;
		c.manufactureCode = null;
		c.transactionSnum = tsec;
		c.commandIdentifier = 0x00;
		byte[] data = new byte[attribs.size() * 2];
		for(int i = 0; i < attribs.size(); i++){
			byte[] b = DataUtil.bytesValue(attribs.get(i));
			data[i * 2] = b[0];
			data[i * 2 + 1] = b[1];
		}
		c.payload = data;
		return c.frame();
	}
	
	static public byte[] write(byte tsec, List<Short> attribs){
		ZclRawCommand c = new ZclRawCommand();
		c.frameControl = 0x00;
		c.manufactureCode = null;
		c.transactionSnum = tsec;
		c.commandIdentifier = 0x00;
		byte[] data = new byte[attribs.size() * 2];
		for(int i = 0; i < attribs.size(); i++){
			byte[] b = DataUtil.bytesValue(attribs.get(i));
			data[i * 2] = b[0];
			data[i * 2 + 1] = b[1];
		}
		c.payload = data;
		return c.frame();
	}
//	1 			2 						0/1 			0/2 						0/2 						0/Variable 			0/2
//	Direction Attribute identifier	Attribute data type	Minimum	reporting interval	Maximum	reporting interval	Reportable change 	Timeout	period

	static public byte[] reportConfig(byte tsec, ReportConfig config){
		ZclRawCommand c = new ZclRawCommand();
		c.frameControl = 0x00;
		c.manufactureCode = null;
		c.transactionSnum = tsec;
		c.commandIdentifier = 0x06;

		c.payload = config.frame();
		return c.frame();
	}
	static public byte[] moveToLevel(byte tsec, byte level,short tranTime, boolean withonoff){
		ZclRawCommand c = new ZclRawCommand();
		c.frameControl = 0x01;
		c.manufactureCode = null;
		c.transactionSnum = tsec;
		if(!withonoff)
			c.commandIdentifier = (byte)0x00;
		else
			c.commandIdentifier = (byte)0x04;
		byte[] data = new byte[3];
		data[0] = level;
		byte[] t = DataUtil.bytesValue(tranTime);
		data[1] = t[0];
		data[2] = t[1];
		c.payload = data;
		return c.frame();
	}
	static public byte[] addGroup(short id, String name,byte tsec){
		ZclRawCommand c = new ZclRawCommand();
		c.frameControl = 0x01;
		c.manufactureCode = null;
		c.transactionSnum = tsec;
		c.commandIdentifier = (byte)0;
		byte[] idb = DataUtil.bytesValue(id);
		
		
		byte[] nb = name.getBytes();
		short l = (short)nb.length;
		byte[] lb = DataUtil.bytesValue(l);
		byte[] data = new byte[l + 4];
		data[0] = idb[0];
		data[1] = idb[1];
		data[2] = lb[0];
		data[3] = lb[1];
		for(int i = 0; i < l; i++)
			data[i + 4] = nb[i];
		c.payload = data;
		return c.frame();
	}
	static public byte[] viewGroup(short id,byte tsec){
		ZclRawCommand c = new ZclRawCommand();
		c.frameControl = 0x01;
		c.manufactureCode = null;
		c.transactionSnum = tsec;
		c.commandIdentifier = (byte)1;
		
		byte[] lb = DataUtil.bytesValue(id);
		
		c.payload = lb;
		return c.frame();
	}
	static public byte[] getGroupMember(byte tsec){
		ZclRawCommand c = new ZclRawCommand();
		c.frameControl = 0x01;
		c.manufactureCode = null;
		c.transactionSnum = tsec;
		c.commandIdentifier = (byte)2;
		
		byte[] lb = {(byte)0, (byte)0};
		
		c.payload = lb;
		return c.frame();
	}
	static public byte[] removeGroupMember(byte tsec, short groupId){
		ZclRawCommand c = new ZclRawCommand();
		c.frameControl = 0x01;
		c.manufactureCode = null;
		c.transactionSnum = tsec;
		c.commandIdentifier = (byte)3;
		
		byte[] lb = DataUtil.bytesValue(groupId);
		
		c.payload = lb;
		return c.frame();
	}
	static public byte[] removeAllGroup(byte tsec){
		ZclRawCommand c = new ZclRawCommand();
		c.frameControl = 0x01;
		c.manufactureCode = null;
		c.transactionSnum = tsec;
		c.commandIdentifier = (byte)4;
		return c.frame();
	}
	static public byte[] addGroupIfIdentify(short id, String name,byte tsec){
		ZclRawCommand c = new ZclRawCommand();
		c.frameControl = 0x01;
		c.manufactureCode = null;
		c.transactionSnum = tsec;
		c.commandIdentifier = (byte)5;
		byte[] idb = DataUtil.bytesValue(id);
		
		
		byte[] nb = name.getBytes();
		short l = (short)nb.length;
		byte[] lb = DataUtil.bytesValue(l);
		byte[] data = new byte[l + 4];
		data[0] = idb[0];
		data[1] = idb[1];
		data[2] = lb[0];
		data[3] = lb[1];
		for(int i = 0; i < l; i++)
			data[i + 4] = nb[i];
		c.payload = data;
		return c.frame();
	}

	static{
		
		
	}
	static public byte[] addScene(byte tsec, ZigbeeScene scene){
		ZclRawCommand c = new ZclRawCommand();
		c.frameControl = 0x01;
		c.manufactureCode = null;
		c.transactionSnum = tsec;
		c.commandIdentifier = (byte)0;
		c.payload = scene.payload();
		
		return c.frame();
	}
	static public byte[] viewScene(byte tsec, short group, byte scene){
		ZclRawCommand c = new ZclRawCommand();
		c.frameControl = 0x01;
		c.manufactureCode = null;
		c.transactionSnum = tsec;
		c.commandIdentifier = (byte)1;
		byte[] buf = DataUtil.bytesValue(group);
		c.payload = new byte[]{
				buf[0],
				buf[1],
				scene
		};
		
		return c.frame();
	}
	static public byte[] removeScene(byte tsec, short group, byte scene){
		ZclRawCommand c = new ZclRawCommand();
		c.frameControl = 0x01;
		c.manufactureCode = null;
		c.transactionSnum = tsec;
		c.commandIdentifier = (byte)2;
		byte[] buf = DataUtil.bytesValue(group);
		c.payload = new byte[]{
				buf[0],
				buf[1],
				scene
		};
		
		return c.frame();
	}
	static public byte[] removeAllScene(byte tsec,  byte scene){
		ZclRawCommand c = new ZclRawCommand();
		c.frameControl = 0x01;
		c.manufactureCode = null;
		c.transactionSnum = tsec;
		c.commandIdentifier = (byte)3;
		;
		c.payload = new byte[]{
	
				scene
		};
		
		return c.frame();
	}
	static public byte[] storeScene(byte tsec, short group, byte scene){
		ZclRawCommand c = new ZclRawCommand();
		c.frameControl = 0x01;
		c.manufactureCode = null;
		c.transactionSnum = tsec;
		c.commandIdentifier = (byte)4;
		byte[] buf = DataUtil.bytesValue(group);
		c.payload = new byte[]{
				buf[0],
				buf[1],
				scene
		};
		
		return c.frame();
	}
	static public byte[] recallScene(byte tsec, short group, byte scene){
		ZclRawCommand c = new ZclRawCommand();
		c.frameControl = 0x01;
		c.manufactureCode = null;
		c.transactionSnum = tsec;
		c.commandIdentifier = (byte)5;
		byte[] buf = DataUtil.bytesValue(group);
		c.payload = new byte[]{
				buf[0],
				buf[1],
				scene
		};
		
		return c.frame();
	}
	static public byte[] sceneMembership(byte tsec, short group){
		ZclRawCommand c = new ZclRawCommand();
		c.frameControl = 0x01;
		c.manufactureCode = null;
		c.transactionSnum = tsec;
		c.commandIdentifier = (byte)6;
		byte[] buf = DataUtil.bytesValue(group);
		c.payload = new byte[]{
				buf[0],
				buf[1]

		};
		
		return c.frame();
	}
}
